package com.api.info.web;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jspxcms.core.domain.Attribute;
import com.jspxcms.core.domain.Info;
import com.jspxcms.core.domain.Node;
import com.jspxcms.core.domain.Tag;
import com.jspxcms.core.domain.User;
import com.jspxcms.core.service.AttributeService;
import com.jspxcms.core.service.InfoQueryService;
import com.jspxcms.core.service.ModelService;
import com.jspxcms.core.service.NodeQueryService;
import com.jspxcms.core.service.TagService;
import com.jspxcms.core.service.UserService;
import com.jspxcms.core.support.Context;
import com.api.info.util.Convert;

/**
 * 资产调剂新闻信息接口<br>
 * 暂没有进行用户和权限的验证
 * 
 * @author wangxiaonan@pansoft.com
 * @since 2017年10月14日
 */
@Controller
@RequestMapping("data/info")
public class MInfoPageController {
	/**
	 * 错误页面
	 * 
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "/.jspx", produces = "application/json;charset=utf-8")
	public String notFound(HttpServletRequest request, HttpServletResponse response, Model modelMap) {
		JSONObject rsMsg = new JSONObject();
		rsMsg.put("status", "404");
		rsMsg.put("message", "no id param!");
		return rsMsg.toJSONString();
	}

	public static final String SITE_ID = "siteId";

	public static final String MODEL = "model";
	public static final String MODEL_ID = "modelId";

	/**
	 * 栏目ID
	 */
	public static final String NODE_ID = "nodeId";
	/**
	 * 栏目编码
	 */
	public static final String NODE = "node";
	/**
	 * 栏目编码（支持SQL通配符：%、_）
	 */
	public static final String NODE_NUMBER = "nodeNumber";

	public static final String EXCLUDE_NODE_ID = "excludeNodeId";
	public static final String EXCLUDE_NODE = "excludeNode";
	public static final String EXCLUDE_NODE_NUMBER = "excludeNodeNumber";

	public static final String ATTR_ID = "attrId";
	public static final String ATTR = "attr";

	public static final String SPECIAL_ID = "specialId";
	public static final String SPECIAL_TITLE = "specialTitle";

	public static final String TAG = "tag";
	public static final String TAG_ID = "tagId";
	public static final String TAG_NAME = "tagName";

	public static final String USER = "user";
	public static final String USER_ID = "userId";

	public static final String PRIORITY = "priority";
	public static final String BEGIN_DATE = "beginDate";
	public static final String END_DATE = "endDate";
	public static final String TITLE = "title";
	public static final String INCLUDE_ID = "includeId";
	public static final String EXCLUDE_ID = "excludeId";
	public static final String STATUS = "status";
	public static final String IS_INCLUDE_CHILDREN = "isIncludeChildren";
	public static final String IS_MAIN_NODE_ONLY = "isMainNodeOnly";
	public static final String IS_WITH_IMAGE = "isWithImage";
	public static final String IS_PERM = "isPerm";

	public static final String P1 = "p1";
	public static final String P2 = "p2";
	public static final String P3 = "p3";
	public static final String P4 = "p4";
	public static final String P5 = "p5";
	public static final String P6 = "p6";

	public static final String SORT_TYPE = "sortType";
	public static final String SORT_FIELD = "sortField";
	public static final String PAGE = "page";
	public static final String PAGE_SIZE = "pageSize";

	/**
	 * 分页信息查询
	 * 
	 * @param request
	 * @param response
	 * @param modelMap
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "/page.jspx", produces = "application/json;charset=utf-8")
	public String getInfoPage(HttpServletRequest request, HttpServletResponse response, Model modelMap) {
		JSONObject rsMsg = new JSONObject();
		String callBack = request.getParameter("callback");
		// 获取查询参数
		try {
			Integer[] siteId = Convert.getIntegers(request, SITE_ID, false);
			if (siteId == null) {
				siteId = new Integer[] { Context.getCurrentSite().getId() };
			}

			Integer[] modelId = Convert.getIntegers(request, MODEL_ID, false);
			String[] model = Convert.getStrings(request, MODEL, false);

			Integer[] nodeId = Convert.getIntegers(request, NODE_ID, false);
			String[] node = Convert.getStrings(request, NODE, false);
			String[] nodeNumber = Convert.getStrings(request, NODE_NUMBER, false);

			Integer[] excludeNodeId = Convert.getIntegers(request, EXCLUDE_NODE_ID, false);
			String[] excludeNode = Convert.getStrings(request, EXCLUDE_NODE, false);
			String[] excludeNodeNumber = Convert.getStrings(request, EXCLUDE_NODE_NUMBER, false);

			Integer[] attrId = Convert.getIntegers(request, ATTR_ID, false);
			String[] attr = Convert.getStrings(request, ATTR, false);

			Integer[] tagId = Convert.getIntegers(request, TAG_ID, false);
			String[] tag = Convert.getStrings(request, TAG, false);
			String[] tagName = Convert.getStrings(request, TAG_NAME, false);

			Integer[] specialId = Convert.getIntegers(request, SPECIAL_ID, false);
			String[] specialTitle = Convert.getStrings(request, SPECIAL_TITLE, false);

			Integer[] userId = Convert.getIntegers(request, USER_ID, false);
			String[] user = Convert.getStrings(request, USER, false);

			Integer[] priority = Convert.getIntegers(request, PRIORITY, false);
			Date beginDate = Convert.getDate(request, BEGIN_DATE, false, false);
			Date endDate = Convert.getDate(request, END_DATE, true, false);
			String[] title = Convert.getStrings(request, TITLE, false);

			Integer[] includeId = Convert.getIntegers(request, INCLUDE_ID, false);
			Integer[] excludeId = Convert.getIntegers(request, EXCLUDE_ID, false);
			String[] status = Convert.getStrings(request, STATUS, false);
			if (status == null) {
				status = new String[] { Info.NORMAL };
			}

			boolean isIncludeChildren = Convert.getBoolean(request, IS_INCLUDE_CHILDREN, false, false);
			boolean isMainNodeOnly = Convert.getBoolean(request, IS_MAIN_NODE_ONLY, false, false);
			Boolean isWithImage = Convert.getBoolean(request, IS_WITH_IMAGE, null, false);

			// boolean isPerm = Convert.getBoolean(request, IS_PERM, false);
			Integer[] viewGroupId = null;
			Integer[] viewOrgId = null;
			// if (isPerm) {
			// Collection<MemberGroup> groups = ForeContext.getGroups(env);
			// Collection<Org> orgs = ForeContext.getOrgs(env);
			// if (groups != null && !groups.isEmpty()) {
			// viewGroupId = new Integer[groups.size()];
			// int i = 0;
			// for (MemberGroup group : groups) {
			// viewGroupId[i++] = group.getId();
			// }
			// }
			// if (orgs != null && !orgs.isEmpty()) {
			// viewOrgId = new Integer[orgs.size()];
			// int i = 0;
			// for (Org org : orgs) {
			// viewOrgId[i++] = org.getId();
			// }
			// }
			// }

			String[] treeNumber = null;
			Integer[] mainNodeId = null;
			List<Integer> nodeIdList = getNodeIdList(nodeId, node, nodeNumber, siteId);
			nodeId = nodeIdList.toArray(new Integer[nodeIdList.size()]);
			if (isIncludeChildren) {
				treeNumber = getNodeTreeNumberList(nodeIdList).toArray(new String[nodeIdList.size()]);
				nodeId = null;
			} else if (isMainNodeOnly) {
				mainNodeId = nodeId;
				nodeId = null;
			}

			String[] excludeTreeNumber = null;
			Integer[] excludeMainNodeId = null;
			List<Integer> excludeNodeIdList = getNodeIdList(excludeNodeId, excludeNode, excludeNodeNumber, siteId);
			excludeMainNodeId = excludeNodeIdList.toArray(new Integer[excludeNodeIdList.size()]);
			if (isIncludeChildren) {
				excludeTreeNumber = getNodeTreeNumberList(excludeNodeIdList)
						.toArray(new String[excludeNodeIdList.size()]);
				excludeMainNodeId = null;
			}

			List<Integer> modelIdList = getModelIdList(modelId, model, siteId);
			modelId = modelIdList.toArray(new Integer[modelIdList.size()]);

			List<Integer> attrIdList = getAttrIdList(attrId, attr, siteId);
			attrId = attrIdList.toArray(new Integer[attrIdList.size()]);

			List<Integer> tagIdList = getTagIdList(tagId, tag, siteId);
			tagId = tagIdList.toArray(new Integer[tagIdList.size()]);

			List<Integer> userIdList = getUserIdList(userId, user);
			userId = userIdList.toArray(new Integer[userIdList.size()]);

			Integer[] p1 = Convert.getIntegers(request, P1, false);
			Integer[] p2 = Convert.getIntegers(request, P2, false);
			Integer[] p3 = Convert.getIntegers(request, P3, false);
			Integer[] p4 = Convert.getIntegers(request, P4, false);
			Integer[] p5 = Convert.getIntegers(request, P5, false);
			Integer[] p6 = Convert.getIntegers(request, P6, false);

			Direction sortType = Convert.getSortType(request, SORT_TYPE, false);
			List<String> sortField = Convert.getSortField(request, SORT_FIELD, false,
					new String[] { "priority", "publishDate", "id" });
			Sort sort = new Sort(sortType, sortField);
			int page = Convert.getPage(request, PAGE, false);
			int pageSize = Convert.getPageSize(request, PAGE_SIZE, false);
			Pageable pageable = new PageRequest(page, pageSize, sort);

			// 从cms调取服务获取info数据
			Page<Info> pageInfos = infoQueryService.findPage(modelId, nodeId, attrId, specialId, tagId, siteId,
					mainNodeId, userId, viewGroupId, viewOrgId, treeNumber, specialTitle, tagName, priority, beginDate,
					endDate, title, includeId, excludeId, excludeMainNodeId, excludeTreeNumber, isWithImage, status, p1,
					p2, p3, p4, p5, p6, pageable);

			// 转换数据
			JSONArray news = Convert.infoPage2Json(pageInfos);
			rsMsg.put("content", news);
		} catch (NullPointerException | IllegalArgumentException npe) {
			rsMsg.put("status", "400");
			rsMsg.put("message", npe.getMessage());
			rsMsg.put("content", new JSONArray());
			return rsMsg.toJSONString();
		}
		rsMsg.put("status", "200");
		rsMsg.put("message", "success");
		return callBack + "(" + rsMsg.toJSONString() + ")";
	}

	/**
	 * 获取信息详情
	 * 
	 * @param request
	 * @param response
	 * @param modelMap
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "/{id:[0-9]+}.jspx", produces = "application/json;charset=utf-8")
	public String getInfoMsg(@PathVariable Integer id, HttpServletRequest request, HttpServletResponse response,
			Model modelMap) {
		JSONObject rsMsg = new JSONObject();
		String callBack = request.getParameter("callback");
		if (id == null) {
			rsMsg.put("status", "400");
			rsMsg.put("message", "id not be null");
			return rsMsg.toJSONString();
		}
		Info info = infoQueryService.get(id);

		if (info == null) {
			rsMsg.put("status", "400");
			rsMsg.put("message", "not found news!");
			return rsMsg.toJSONString();
		}
		JSONObject infoMsg = new JSONObject(Convert.info2Json(info));

		rsMsg.put("status", "200");
		rsMsg.put("message", "success");
		rsMsg.put("content", infoMsg);
		return callBack + "(" + rsMsg.toJSONString() + ")";
	}

	/**
	 * 根据参数nodeId、node、nodeNumber和siteId得到nodeId的汇总。
	 * 
	 * @param nodeId
	 * @param node
	 * @param nodeNumber
	 * @param siteId
	 * @return
	 */
	private List<Integer> getNodeIdList(Integer[] nodeId, String[] node, String[] nodeNumber, Integer[] siteId) {
		List<Integer> list = new ArrayList<Integer>();
		if (ArrayUtils.isNotEmpty(nodeId)) {
			list.addAll(Arrays.asList(nodeId));
		}
		if (ArrayUtils.isNotEmpty(node)) {
			List<Node> nodes = nodeQuery.findByNumber(node, siteId);
			for (Node n : nodes) {
				list.add(n.getId());
			}
		}
		if (ArrayUtils.isNotEmpty(nodeNumber)) {
			List<Node> nodes = nodeQuery.findByNumberLike(nodeNumber, siteId);
			for (Node n : nodes) {
				list.add(n.getId());
			}
		}
		return list;
	}

	/**
	 * 得到node子节点
	 * 
	 * @param nodeList
	 * @return
	 */
	private List<String> getNodeTreeNumberList(List<Integer> nodeList) {
		List<String> numbers = new ArrayList<String>(nodeList.size());
		Node node;
		for (Integer nodeId : nodeList) {
			node = nodeQuery.get(nodeId);
			numbers.add(node.getTreeNumber());
		}
		return numbers;
	}

	private List<Integer> getModelIdList(Integer[] modelId, String[] model, Integer[] siteId) {
		List<Integer> list = new ArrayList<Integer>();
		if (ArrayUtils.isNotEmpty(modelId)) {
			list.addAll(Arrays.asList(modelId));
		}
		List<com.jspxcms.core.domain.Model> models = modelService.findByNumbers(model, siteId);
		for (com.jspxcms.core.domain.Model m : models) {
			list.add(m.getId());
		}
		return list;
	}

	private List<Integer> getAttrIdList(Integer[] attrId, String[] attr, Integer[] siteId) {
		List<Integer> list = new ArrayList<Integer>();
		if (ArrayUtils.isNotEmpty(attrId)) {
			list.addAll(Arrays.asList(attrId));
		}
		List<Attribute> attrs = attributeService.findByNumbers(attr, siteId);
		for (Attribute a : attrs) {
			list.add(a.getId());
		}
		return list;
	}

	private List<Integer> getTagIdList(Integer[] tagId, String[] tag, Integer[] siteId) {
		List<Integer> list = new ArrayList<Integer>();
		if (ArrayUtils.isNotEmpty(tagId)) {
			list.addAll(Arrays.asList(tagId));
		}
		List<Tag> tags = tagService.findByName(tag, siteId);
		for (Tag t : tags) {
			list.add(t.getId());
		}
		return list;
	}

	private List<Integer> getUserIdList(Integer[] userId, String[] user) {
		List<Integer> list = new ArrayList<Integer>();
		if (ArrayUtils.isNotEmpty(userId)) {
			list.addAll(Arrays.asList(userId));
		}
		List<User> users = userService.findByUsername(user);
		for (User u : users) {
			list.add(u.getId());
		}
		return list;
	}

	@Autowired
	NodeQueryService nodeQuery;
	@Autowired
	InfoQueryService infoQueryService;
	@Autowired
	private ModelService modelService;
	@Autowired
	private UserService userService;
	@Autowired
	private TagService tagService;
	@Autowired
	private AttributeService attributeService;
}
